// MonitorController.java
package com.example.micrometerdemo.controller;

import com.example.micrometerdemo.constant.MetricName;
import com.example.micrometerdemo.constant.MetricTag;
import io.micrometer.core.annotation.Counted;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.LongTaskTimer;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

@RestController
@Slf4j
public class MonitorController {

    private final AtomicInteger queueSize = new AtomicInteger(0);
    private final AtomicLong cacheExpiryNanos = new AtomicLong();
    private final ExecutorService executor = Executors.newFixedThreadPool(2);


    @GetMapping("/metrics")
    @Timed(value = MetricName.TIMER,extraTags = {MetricTag.GROUP_TAG,"annotation_metrics"})
    @Counted(value = MetricName.COUNTER,extraTags = {MetricTag.GROUP_TAG,"annotation_metrics"})
    public String metrics() {
        for (int i = 0; i < 10; i++) {
            int idx=i+1;
            log.info("模拟第{}次数据开始",idx);
            mockManualMetrics();
            log.info("模拟第{}次数据结束",idx);
        }
        return "S";
    }

    private void mockManualMetrics() {
        Random random = new Random();
        // 计数器
        Metrics.counter(MetricName.COUNTER, MetricTag.GROUP_TAG, "manual_metrics")
                .increment(random.nextInt(5)+1);;

        // 仪表盘
        List<Tag> gaugeTags=List.of(Tag.of(MetricName.GAUGE,"queue1"));
        Metrics.gauge(MetricName.GAUGE,gaugeTags,queueSize,AtomicInteger::get);
               /* .description("消息队列大小")
                .tag(MetricName.GAUGE,"queue1")
                .register(MetricUtils.getMeterRegistry());*/

        // 时间仪表盘
        List<Tag> timeGaugeTags=List.of(Tag.of(MetricName.TIMER_GAUGE,"key1"));
        Metrics.more().timeGauge(MetricName.TIMER_GAUGE,timeGaugeTags,cacheExpiryNanos,TimeUnit.MICROSECONDS, AtomicLong::get);
               /* .description("缓存剩余时间")
                .tag(MetricName.TIMER_GAUGE,"key1")
                .register(MetricUtils.getMeterRegistry());*/

        // 计时器
        Metrics.timer(MetricName.TIMER, MetricTag.GROUP_TAG, "manual_metrics").record(() -> {
            try {
                TimeUnit.SECONDS.sleep(random.nextInt(5)+1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        // 长任务计时器
        LongTaskTimer longTaskTimer = Metrics
                .more()
                .longTaskTimer(MetricName.LONG_TASK_TIMER, MetricTag.GROUP_TAG, "test1", "type", "http");
        executor.submit(()->{
            LongTaskTimer.Sample sample1 = longTaskTimer.start();
            try {
                TimeUnit.SECONDS.sleep(random.nextInt(5)+1);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                // 上报
                sample1.stop();
            }
        });

        // 分布摘要
         Metrics.summary(MetricName.DISTRIBUTION_SUMMARY, MetricTag.GROUP_TAG, "test1")
                 .record(random.nextInt(5)+1);
    }
}